---
title: 工具系统概述 | Kastrax 文档
description: Kastrax 工具系统的详细介绍，包括工具定义、注册、调用和自定义工具的创建方法。
---

# 工具系统概述 ✅

Kastrax 工具系统允许代理与外部系统交互、访问数据和执行操作。本指南解释了工具系统的架构以及如何有效地使用它。

> 如果您正在使用 Kotlin 开发，请查看 [Kotlin 工具系统概述](./overview-kotlin.mdx) 获取更详细的 Kotlin 特定指南。

## 什么是工具？ ✅

在 Kastrax 中，工具是代理可以调用的函数，使其能够：

- 执行计算和数据处理
- 与外部系统交互
- 访问和修改文件
- 搜索网络信息
- 执行特定领域的操作

工具扩展了代理的能力，使其不仅限于生成文本，还能执行实际操作。

## 工具系统架构 ✅

Kastrax 工具系统由几个组件组成：

1. **工具定义**：工具如何被定义和注册
2. **工具执行**：代理如何执行工具
3. **工具参数**：工具参数如何定义和验证
4. **工具结果**：工具结果如何处理和返回

## 基本工具创建 ✅

以下是创建工具的简单示例：

```kotlin
import ai.kastrax.core.agent.agent
import ai.kastrax.core.tools.tool
import ai.kastrax.integrations.deepseek.deepSeek
import ai.kastrax.integrations.deepseek.DeepSeekModel
import kotlinx.coroutines.runBlocking

fun createAgentWithTools() = agent {
    name("工具代理")
    description("具有工具能力的代理")

    // 配置 LLM
    model = deepSeek {
        apiKey("your-deepseek-api-key")
        model(DeepSeekModel.DEEPSEEK_CHAT)
        temperature(0.7)
    }

    // 添加工具
    tools {
        // 无参数的简单工具
        tool("getCurrentTime") {
            description("获取当前时间")
            parameters {}
            execute {
                val currentTime = java.time.LocalDateTime.now()
                val formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                val formattedTime = currentTime.format(formatter)
                "当前时间是 $formattedTime"
            }
        }

        // 带参数的工具
        tool("calculateSum") {
            description("计算两个数字的和")
            parameters {
                parameter("a", "第一个数字", Double::class)
                parameter("b", "第二个数字", Double::class)
            }
            execute { params ->
                val a = params["a"] as Double
                val b = params["b"] as Double
                val sum = a + b
                "$a 加 $b 的和是 $sum"
            }
        }
    }
}

fun main() = runBlocking {
    val agent = createAgentWithTools()

    // 测试代理
    println(agent.generate("现在几点了？").text)
    println(agent.generate("计算 5.2 和 3.8 的和").text)
}
```

## 工具参数

工具可以有各种类型的参数：

```kotlin
tool("searchDatabase") {
    description("在数据库中搜索记录")
    parameters {
        parameter("query", "搜索查询", String::class)
        parameter("limit", "最大结果数", Int::class, optional = true, defaultValue = 10)
        parameter("sortBy", "排序字段", String::class, optional = true)
        parameter("ascending", "升序排序", Boolean::class, optional = true, defaultValue = true)
    }
    execute { params ->
        val query = params["query"] as String
        val limit = params["limit"] as Int
        val sortBy = params["sortBy"] as String?
        val ascending = params["ascending"] as Boolean

        // 执行数据库搜索
        // ...

        "为查询 '$query' 找到 $limit 条结果"
    }
}
```

## 工具分类

您可以将工具组织成类别：

```kotlin
tools {
    // 数学工具
    category("数学") {
        tool("add") {
            description("加两个数")
            parameters {
                parameter("a", "第一个数", Double::class)
                parameter("b", "第二个数", Double::class)
            }
            execute { params ->
                val a = params["a"] as Double
                val b = params["b"] as Double
                "结果: ${a + b}"
            }
        }

        tool("subtract") {
            description("减两个数")
            parameters {
                parameter("a", "第一个数", Double::class)
                parameter("b", "第二个数", Double::class)
            }
            execute { params ->
                val a = params["a"] as Double
                val b = params["b"] as Double
                "结果: ${a - b}"
            }
        }
    }

    // 实用工具
    category("实用工具") {
        tool("getCurrentTime") {
            description("获取当前时间")
            parameters {}
            execute {
                "当前时间: ${java.time.LocalDateTime.now()}"
            }
        }
    }
}
```

## 异步工具

对于长时间运行的操作，您可以创建异步工具：

```kotlin
tool("fetchLargeDataset") {
    description("从 API 获取大型数据集")
    parameters {
        parameter("datasetId", "数据集 ID", String::class)
    }
    executeAsync { params ->
        val datasetId = params["datasetId"] as String

        // 模拟长时间运行的操作
        kotlinx.coroutines.delay(2000)

        // 返回结果
        "数据集 $datasetId 成功获取，包含 10,000 条记录"
    }
}
```

## 工具错误处理

您可以在工具中处理错误：

```kotlin
tool("divideNumbers") {
    description("除两个数")
    parameters {
        parameter("a", "被除数", Double::class)
        parameter("b", "除数", Double::class)
    }
    execute { params ->
        val a = params["a"] as Double
        val b = params["b"] as Double

        try {
            if (b == 0.0) {
                throw ArithmeticException("除以零")
            }
            "结果: ${a / b}"
        } catch (e: Exception) {
            "错误: ${e.message}"
        }
    }
}
```

## 工具验证

您可以为工具参数添加验证：

```kotlin
tool("sendEmail") {
    description("发送电子邮件")
    parameters {
        parameter("to", "收件人电子邮件地址", String::class) {
            validate { email ->
                if (!email.contains("@")) {
                    throw IllegalArgumentException("无效的电子邮件地址")
                }
            }
        }
        parameter("subject", "邮件主题", String::class) {
            validate { subject ->
                if (subject.length > 100) {
                    throw IllegalArgumentException("主题太长（最多 100 个字符）")
                }
            }
        }
        parameter("body", "邮件正文", String::class)
    }
    execute { params ->
        val to = params["to"] as String
        val subject = params["subject"] as String
        val body = params["body"] as String

        // 发送邮件逻辑
        // ...

        "邮件已发送至 $to"
    }
}
```

## 工具权限

您可以为工具定义权限：

```kotlin
tool("deleteFile") {
    description("删除文件")
    permissions {
        permission("file.delete", "删除文件的权限")
    }
    parameters {
        parameter("path", "文件路径", String::class)
    }
    execute { params ->
        val path = params["path"] as String

        // 检查权限
        if (!hasPermission("file.delete")) {
            return "错误: 权限被拒绝"
        }

        // 删除文件逻辑
        // ...

        "文件 $path 已成功删除"
    }
}
```

## 工具组合

您可以从其他工具组合工具：

```kotlin
// 定义基础工具
val getCurrentTimeToolDef = toolDefinition("getCurrentTime") {
    description("获取当前时间")
    parameters {}
    execute {
        val currentTime = java.time.LocalDateTime.now()
        val formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
        val formattedTime = currentTime.format(formatter)
        "当前时间是 $formattedTime"
    }
}

val getCurrentDateToolDef = toolDefinition("getCurrentDate") {
    description("获取当前日期")
    parameters {}
    execute {
        val currentDate = java.time.LocalDate.now()
        val formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")
        val formattedDate = currentDate.format(formatter)
        "当前日期是 $formattedDate"
    }
}

// 组合新工具
val getDateTimeInfoToolDef = toolDefinition("getDateTimeInfo") {
    description("获取当前日期和时间信息")
    parameters {}
    execute {
        val timeResult = getCurrentTimeToolDef.execute(mapOf())
        val dateResult = getCurrentDateToolDef.execute(mapOf())
        "$dateResult\n$timeResult"
    }
}

// 将组合工具添加到代理
agent {
    // ...
    tools {
        addTool(getDateTimeInfoToolDef)
    }
}
```

## 外部 API 工具

您可以创建与外部 API 交互的工具：

```kotlin
tool("getWeather") {
    description("获取位置的天气信息")
    parameters {
        parameter("location", "城市名称或坐标", String::class)
    }
    execute { params ->
        val location = params["location"] as String

        // 发起 API 请求
        val apiKey = "your-weather-api-key"
        val url = "https://api.weatherapi.com/v1/current.json?key=$apiKey&q=$location"

        try {
            val client = java.net.http.HttpClient.newBuilder().build()
            val request = java.net.http.HttpRequest.newBuilder()
                .uri(java.net.URI.create(url))
                .GET()
                .build()

            val response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString())

            if (response.statusCode() == 200) {
                // 解析 JSON 响应
                // 这是一个简化的示例
                val body = response.body()
                "$location 的天气信息: $body"
            } else {
                "获取天气时出错: ${response.statusCode()}"
            }
        } catch (e: Exception) {
            "错误: ${e.message}"
        }
    }
}
```

## 文件操作工具

您可以创建文件操作工具：

```kotlin
tools {
    category("文件操作") {
        tool("readFile") {
            description("读取文件内容")
            parameters {
                parameter("path", "文件路径", String::class)
            }
            execute { params ->
                val path = params["path"] as String

                try {
                    val content = java.nio.file.Files.readString(java.nio.file.Path.of(path))
                    "文件内容:\n$content"
                } catch (e: Exception) {
                    "读取文件时出错: ${e.message}"
                }
            }
        }

        tool("writeFile") {
            description("将内容写入文件")
            parameters {
                parameter("path", "文件路径", String::class)
                parameter("content", "要写入的内容", String::class)
            }
            execute { params ->
                val path = params["path"] as String
                val content = params["content"] as String

                try {
                    java.nio.file.Files.writeString(java.nio.file.Path.of(path), content)
                    "内容已成功写入 $path"
                } catch (e: Exception) {
                    "写入文件时出错: ${e.message}"
                }
            }
        }
    }
}
```

## 数据库工具

您可以创建数据库操作工具：

```kotlin
tools {
    category("数据库") {
        tool("queryDatabase") {
            description("执行 SQL 查询")
            parameters {
                parameter("query", "SQL 查询", String::class)
            }
            execute { params ->
                val query = params["query"] as String

                // 这是一个简化的示例
                // 在实际应用中，您会使用适当的数据库连接
                try {
                    // 执行查询
                    // ...

                    "查询成功执行。结果:\n..."
                } catch (e: Exception) {
                    "执行查询时出错: ${e.message}"
                }
            }
        }
    }
}
```

## 工具注册

您可以从外部源注册工具：

```kotlin
// 在单独的文件中定义工具
object MathTools {
    val addTool = toolDefinition("add") {
        description("加两个数")
        parameters {
            parameter("a", "第一个数", Double::class)
            parameter("b", "第二个数", Double::class)
        }
        execute { params ->
            val a = params["a"] as Double
            val b = params["b"] as Double
            "结果: ${a + b}"
        }
    }

    val subtractTool = toolDefinition("subtract") {
        description("减两个数")
        parameters {
            parameter("a", "第一个数", Double::class)
            parameter("b", "第二个数", Double::class)
        }
        execute { params ->
            val a = params["a"] as Double
            val b = params["b"] as Double
            "结果: ${a - b}"
        }
    }
}

// 向代理注册工具
agent {
    // ...
    tools {
        addTool(MathTools.addTool)
        addTool(MathTools.subtractTool)
    }
}
```

## 完整示例

以下是包含各种工具的完整示例：

```kotlin
import ai.kastrax.core.agent.agent
import ai.kastrax.core.tools.tool
import ai.kastrax.integrations.deepseek.deepSeek
import ai.kastrax.integrations.deepseek.DeepSeekModel
import kotlinx.coroutines.runBlocking
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

fun createToolAgent() = agent {
    name("实用助手")
    description("具有各种实用工具的助手")

    // 配置 LLM
    model = deepSeek {
        apiKey("your-deepseek-api-key")
        model(DeepSeekModel.DEEPSEEK_CHAT)
        temperature(0.7)
    }

    // 添加工具
    tools {
        // 日期和时间工具
        category("日期时间") {
            tool("getCurrentTime") {
                description("获取当前时间")
                parameters {}
                execute {
                    val currentTime = LocalDateTime.now()
                    val formatter = DateTimeFormatter.ofPattern("HH:mm:ss")
                    val formattedTime = currentTime.format(formatter)
                    "当前时间是 $formattedTime"
                }
            }

            tool("getCurrentDate") {
                description("获取当前日期")
                parameters {}
                execute {
                    val currentDate = LocalDateTime.now()
                    val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
                    val formattedDate = currentDate.format(formatter)
                    "今天的日期是 $formattedDate"
                }
            }
        }

        // 数学工具
        category("数学") {
            tool("calculate") {
                description("执行计算")
                parameters {
                    parameter("expression", "数学表达式", String::class)
                }
                execute { params ->
                    val expression = params["expression"] as String

                    try {
                        // 这是一个简化的示例
                        // 在实际应用中，您会使用适当的表达式求值器
                        val result = when {
                            expression.contains("+") -> {
                                val parts = expression.split("+")
                                val a = parts[0].trim().toDouble()
                                val b = parts[1].trim().toDouble()
                                a + b
                            }
                            expression.contains("-") -> {
                                val parts = expression.split("-")
                                val a = parts[0].trim().toDouble()
                                val b = parts[1].trim().toDouble()
                                a - b
                            }
                            expression.contains("*") -> {
                                val parts = expression.split("*")
                                val a = parts[0].trim().toDouble()
                                val b = parts[1].trim().toDouble()
                                a * b
                            }
                            expression.contains("/") -> {
                                val parts = expression.split("/")
                                val a = parts[0].trim().toDouble()
                                val b = parts[1].trim().toDouble()
                                if (b == 0.0) throw ArithmeticException("除以零")
                                a / b
                            }
                            else -> throw IllegalArgumentException("不支持的操作")
                        }

                        "结果: $result"
                    } catch (e: Exception) {
                        "计算结果时出错: ${e.message}"
                    }
                }
            }
        }

        // 实用工具
        category("实用工具") {
            tool("generateRandomNumber") {
                description("在范围内生成随机数")
                parameters {
                    parameter("min", "最小值", Int::class)
                    parameter("max", "最大值", Int::class)
                }
                execute { params ->
                    val min = params["min"] as Int
                    val max = params["max"] as Int

                    if (min >= max) {
                        "错误: 最小值必须小于最大值"
                    } else {
                        val random = java.util.Random()
                        val randomNumber = random.nextInt(max - min + 1) + min
                        "$min 和 $max 之间的随机数: $randomNumber"
                    }
                }
            }

            tool("countWords") {
                description("计算文本中的单词数")
                parameters {
                    parameter("text", "要分析的文本", String::class)
                }
                execute { params ->
                    val text = params["text"] as String
                    val wordCount = text.split("\\s+".toRegex()).filter { it.isNotEmpty() }.size
                    "单词数: $wordCount"
                }
            }
        }
    }
}

fun main() = runBlocking {
    val agent = createToolAgent()

    // 测试代理
    println(agent.generate("现在几点了？").text)
    println(agent.generate("计算 15.5 + 27.3").text)
    println(agent.generate("在 1 到 100 之间生成一个随机数").text)
    println(agent.generate("计算 '敏捷的棕色狐狸跳过懒狗' 中的单词数").text)
}
```

## 类型安全的 Zod 工具 ✅

Kastrax 提供了受 Zod 启发的模式系统，用于创建类型安全的工具：

```kotlin
import ai.kastrax.core.tools.zodTool
import ai.kastrax.zod.*

// 定义输入和输出类型
data class CalculatorInput(
    val operation: String,
    val a: Double,
    val b: Double
)

data class CalculatorOutput(
    val result: Double
)

// 创建类型安全的工具
val calculatorTool = zodTool<CalculatorInput, CalculatorOutput> {
    id = "calculator"
    name = "计算器"
    description = "执行基本的数学运算"

    // 定义输入模式
    inputSchema = objectInput("计算器输入") {
        stringField("operation", "要执行的操作") {
            enum("add", "subtract", "multiply", "divide")
        }
        numberField("a", "第一个操作数")
        numberField("b", "第二个操作数")
    }.transform { input ->
        CalculatorInput(
            operation = input["operation"] as String,
            a = (input["a"] as Number).toDouble(),
            b = (input["b"] as Number).toDouble()
        )
    }

    // 定义输出模式
    outputSchema = objectOutput("计算器输出") {
        numberField("result", "运算结果")
    }.transform { output ->
        CalculatorOutput(
            result = (output["result"] as Number).toDouble()
        )
    }

    // 实现执行逻辑
    execute = { input ->
        val result = when (input.operation) {
            "add" -> input.a + input.b
            "subtract" -> input.a - input.b
            "multiply" -> input.a * input.b
            "divide" -> input.a / input.b
            else -> throw IllegalArgumentException("未知操作: ${input.operation}")
        }

        CalculatorOutput(result)
    }
}
```

### Zod 模式系统的优势

使用 Zod 模式系统创建工具有以下优势：

1. **类型安全**：在编译时捕获类型错误
2. **输入验证**：自动验证工具输入
3. **数据转换**：在验证后转换数据
4. **清晰的 API**：使用链式 API 定义模式
5. **与数据类集成**：方便地与 Kotlin 数据类集成

### 简单的 Zod 工具示例

以下是一个简单的字符串反转工具：

```kotlin
import ai.kastrax.core.tools.zodTool
import ai.kastrax.zod.stringInput
import ai.kastrax.zod.stringOutput
import kotlinx.coroutines.runBlocking

fun main() {
    // 创建一个简单的字符串反转工具
    val reverseStringTool = zodTool<String, String> {
        id = "reverse_string"
        name = "字符串反转"
        description = "反转输入的字符串"

        // 使用 stringInput 和 stringOutput 辅助函数创建模式
        inputSchema = stringInput("要反转的字符串")
        outputSchema = stringOutput("反转后的字符串")

        // 实现执行逻辑
        execute = { input ->
            input.reversed()
        }
    }

    // 使用工具
    val input = "你好，世界！"

    // 执行工具
    val output = runBlocking {
        reverseStringTool.execute(input)
    }

    println("原始字符串: $input")
    println("反转后的字符串: $output")
}
```

## 下一步

现在您已经了解了工具系统，您可以：

1. 了解 [Zod 工具](./zod-tools.mdx)
2. 探索[自定义工具开发](./custom-tools.mdx)
3. 实现[工具链](./tool-chains.mdx)
